#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string>
#include <uv.h>

using namespace std;

uv_fs_t open_req;
uv_fs_t read_req;
uv_fs_t write_req;

uv_buf_t buf;

void on_write(uv_fs_t *req);

void on_read(uv_fs_t *req);

void on_open(uv_fs_t *req);

void on_write(uv_fs_t *req) {
  if (req->result < 0) {
    fprintf(stderr, "write error: %s\n", uv_strerror(req->result));
  } else {
    uv_fs_read(uv_default_loop(), &read_req, open_req.result, &buf, 1, -1, on_read);
  }
}

void on_read(uv_fs_t *req) {
  if (req->result < 0) {
    fprintf(stderr, "read error: %s\n", uv_strerror(req->result));
  } else if (req->result == 0) {
    uv_fs_t close_req;
    uv_fs_close(uv_default_loop(), &close_req, open_req.result, NULL);
  } else if (req->result > 0) {
    buf.len = req->result;
    uv_fs_write(uv_default_loop(), &write_req, 1, &buf, 1, -1, on_write);
  }
}

void on_open(uv_fs_t *req) {
  fprintf(stderr, "%d\n", req);
  assert(req == &open_req);
  //result表示request的结果，0表示error，其他表示成功
  //read和write方法中，表示可读或者可写的数据量，这里表示文件句柄
  if (req->result >= 0) {
    char buffer[12] = {0x00};
    buf = uv_buf_init(buffer, sizeof(buffer));
    uv_fs_read(uv_default_loop(), &read_req, req->result, &buf, 1, -1, on_read);
  } else {
    fprintf(stderr, "error opening file: %s\n", uv_strerror(req->result));
  }
}

int main() {
  string filePath = "test.txt";
  fprintf(stderr, "%d\n", &open_req);
  uv_fs_open(uv_default_loop(), &open_req, filePath.c_str(), O_RDONLY, 0, on_open);

  uv_run(uv_default_loop(), UV_RUN_DEFAULT);

  uv_fs_req_cleanup(&open_req);
  uv_fs_req_cleanup(&read_req);
  uv_fs_req_cleanup(&write_req);
  return 0;
}
